import { HttpException, HttpStatus, Injectable, Render } from "@nestjs/common";
import { Express } from "express";
import * as path from "path";
import * as fs from "fs-extra";
import * as moment from "moment";
import IHelper from "@/services/helper.service";
import IConstants from "@/core/constants";
import IResponse from "@/services/response.service";
import { ConfigService } from "@nestjs/config";
import { ReqProvider } from "@/core/providers/req.provider";
import { Observable, defer, delay, map, tap, of, concatMap, from } from "rxjs";
import { RedisProvider } from "@/core/providers/redis.provider";
import OpenAI from "openai";
import http from "http";
import { HttpsProxyAgent } from "https-proxy-agent";

@Injectable()
export class SharedService {
  constructor(
    private readonly configService: ConfigService,
    private readonly reqProvider: ReqProvider,
    private readonly redisProvider: RedisProvider,
  ) {
    fs.ensureDirSync(path.join(IConstants.publicDir, "uploads"));
  }

  getDownloads() {
    const downloadPath = path.join(IConstants.publicDir, "downloads");
    const list = [];
    fs.readdirSync(downloadPath).forEach((file) => {
      list.push({ path: path.join("/static/downloads", file), name: file });
    });
    return { list, time: Date.now() };
  }
  getWowImages(query: any) {
    const downloadPath = path.join(IConstants.publicDir, "wow");
    const list = [];
    fs.readdirSync(downloadPath).forEach((file) => {
      list.push({ path: path.join("/static/wow", file), name: file });
    });
    return { list, time: Date.now(), img: list[query?.id || 0] };
  }

  upload(file: Express.Multer.File) {
    const ALLOW_EXT_LIST: string[] = [".JPG", ".PNG", ".JPEG", ".MP4"];
    const MAX_SIZE: number = 500 * 1000 * 1000;
    const extname = path.extname(file.originalname);
    if (file.size > MAX_SIZE) {
      throw new HttpException(
        "File size cannot exceed 5M",
        HttpStatus.BAD_REQUEST,
      );
    }
    if (!ALLOW_EXT_LIST.includes(extname.toUpperCase())) {
      throw new HttpException(
        "The extname not supported to upload.",
        HttpStatus.BAD_REQUEST,
      );
    }
    const relativePath = path.join(
      "uploads",
      moment().format("YYYY/MM/DD"),
      `${IHelper.hash(32)}${extname}`,
    );
    const absoluteFilepath = path.join(IConstants.publicDir, relativePath);
    fs.ensureFileSync(absoluteFilepath);
    fs.writeFileSync(absoluteFilepath, file.buffer);
    const url = path.join(
      this.configService.get("STATIC_PREFIX", "static"),
      relativePath,
    );
    const finalUrl = ["", ...url.split(path.sep)].join("/");
    return of(null).pipe(
      delay(1000),
      map(() => IResponse.success({ url: finalUrl })),
    );
  }

  debug(id: number) {
    return this[`debug${id}`]();
  }

  debug1() {
    const openai = new OpenAI({
      // apiKey: this.configService.get("OPENAI_APIKEY"),
      apiKey: "sk-yh69VFtNcDFH7DwH07A430E1FfF744E39a280033963067D5",
      httpAgent: new HttpsProxyAgent(
        this.configService.get("OPENAI_PROXY_URL"),
      ),
    });
    return openai.chat.completions.create({
      messages: [{ role: "user", content: "Say this is a test" }],
      model: "gpt-3.5-turbo",
    });
  }
  debug2() {
    let str =
      "{SCROLLLOCK}, {VK_SPACE}, {VK_LSHIFT}, {VK_PAUSE}, {VK_MODECHANGE},{BACK}, {VK_HOME}, {F23}, {F22}, {F21}, {F20}, {VK_HANGEUL}, {VK_KANJI},{VK_RIGHT}, {BS}, {HOME}, {VK_F4}, {VK_ACCEPT}, {VK_F18}, {VK_SNAPSHOT},{VK_PA1}, {VK_NONAME}, {VK_LCONTROL}, {ZOOM}, {VK_ATTN}, {VK_F10}, {VK_F22},{VK_F23}, {VK_F20}, {VK_F21}, {VK_SCROLL}, {TAB}, {VK_F11}, {VK_END},{LEFT}, {VK_UP}, {NUMLOCK}, {VK_APPS}, {PGUP}, {VK_F8}, {VK_CONTROL},{VK_LEFT}, {PRTSC}, {VK_NUMPAD4}, {CAPSLOCK}, {VK_CONVERT}, {VK_PROCESSKEY},{ENTER}, {VK_SEPARATOR}, {VK_RWIN}, {VK_LMENU}, {VK_NEXT}, {F1}, {F2},{F3}, {F4}, {F5}, {F6}, {F7}, {F8}, {F9}, {VK_ADD}, {VK_RCONTROL},{VK_RETURN}, {BREAK}, {VK_NUMPAD9}, {VK_NUMPAD8}, {RWIN}, {VK_KANA},{PGDN}, {VK_NUMPAD3}, {DEL}, {VK_NUMPAD1}, {VK_NUMPAD0}, {VK_NUMPAD7},{VK_NUMPAD6}, {VK_NUMPAD5}, {DELETE}, {VK_PRIOR}, {VK_SUBTRACT}, {HELP},{VK_PRINT}, {VK_BACK}, {CAP}, {VK_RBUTTON}, {VK_RSHIFT}, {VK_LWIN}, {DOWN},{VK_HELP}, {VK_NONCONVERT}, {BACKSPACE}, {VK_SELECT}, {VK_TAB}, {VK_HANJA},{VK_NUMPAD2}, {INSERT}, {VK_F9}, {VK_DECIMAL}, {VK_FINAL}, {VK_EXSEL},{RMENU}, {VK_F3}, {VK_F2}, {VK_F1}, {VK_F7}, {VK_F6}, {VK_F5}, {VK_CRSEL},{VK_SHIFT}, {VK_EREOF}, {VK_CANCEL}, {VK_DELETE}, {VK_HANGUL}, {VK_MBUTTON},{VK_NUMLOCK}, {VK_CLEAR}, {END}, {VK_MENU}, {SPACE}, {BKSP}, {VK_INSERT},{F18}, {F19}, {ESC}, {VK_MULTIPLY}, {F12}, {F13}, {F10}, {F11}, {F16},{F17}, {F14}, {F15}, {F24}, {RIGHT}, {VK_F24}, {VK_CAPITAL}, {VK_LBUTTON},{VK_OEM_CLEAR}, {VK_ESCAPE}, {UP}, {VK_DIVIDE}, {INS}, {VK_JUNJA},{VK_F19}, {VK_EXECUTE}, {VK_PLAY}, {VK_RMENU}, {VK_F13}, {VK_F12}, {LWIN},{VK_DOWN}, {VK_F17}, {VK_F16}, {VK_F15}, {VK_F14}";
    let list = str.split(",").map((e) => e.trim())
    return { list };
  }
}
